home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume6 / rpc2 / part09 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  50.0 KB

  1. Subject:  v06i097:  Sun RPC Source (rpc2), Part09/11
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: cca!SUN.COM!marks (Mark Stein)
  6. Mod.sources: Volume 6, Issue 97
  7. Archive-name: rpc2/Part09
  8.  
  9. [ #include <same-disclaimer-you've-seen-on-all-other-parts.h> --r$ ]
  10.  
  11. Sun RPC source (part 9 of 11).  This software package contains code
  12. and documentation for Revision 3.0 of the Sun Remote Procedure Call
  13. library.  In addition, a beta version of the XDR/RPC protocol compiler
  14. is included.  Comments about this latest release may be mailed to
  15. sun!rpc or rpc@sun.com.
  16.  
  17. Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  18. unrestricted use provided that this legend is included on all tape
  19. media and as a part of the software program in whole or part.  Users
  20. may copy or modify Sun RPC without charge, but are not authorized to
  21. license or distribute it to anyone else except as part of a product or
  22. program developed by the user.
  23.  
  24. - - - - - - - - - C U T - H E R E - - - - - - - - - - - - - - - - - -
  25. #! /bin/sh
  26. # This is a shell archive, meaning:
  27. # 1. Remove everything above the #! /bin/sh line.
  28. # 2. Save the resulting text in a file.
  29. # 3. Execute the file with /bin/sh (not csh) to create:
  30. #    rpc/rpclib/xdr_float.c
  31. #    rpc/rpclib/xdr_mem.c
  32. #    rpc/rpclib/xdr_rec.c
  33. #    rpc/rpclib/xdr_reference.c
  34. #    rpc/rpclib/xdr_stdio.c
  35. #    rpc/tools/portmap.8c
  36. #    rpc/tools/portmap.c
  37. # This archive created: Mon Jul 14 16:55:40 1986
  38. export PATH; PATH=/bin:/usr/bin:$PATH
  39. for d in rpc rpc/doc rpc/rpclib rpc/tools rpc/toys rpc/rpclib/profiled rpc/rpcgen rpc/rpcgen/test
  40. do
  41.     if test ! -d $d
  42.     then
  43.         echo "shar: Making directory $d"
  44.         mkdir $d
  45.         chmod 755 $d
  46.     fi
  47. done
  48. echo shar: "extracting 'rpc/rpclib/xdr_float.c'" '(6623 characters)'
  49. if test -f 'rpc/rpclib/xdr_float.c'
  50. then
  51.     echo shar: "will not over-write existing file 'rpc/rpclib/xdr_float.c'"
  52. else
  53. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_float.c'
  54. X/*
  55. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  56. X * unrestricted use provided that this legend is included on all tape
  57. X * media and as a part of the software program in whole or part.  Users
  58. X * may copy or modify Sun RPC without charge, but are not authorized
  59. X * to license or distribute it to anyone else except as part of a product or
  60. X * program developed by the user.
  61. X * 
  62. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  63. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  64. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  65. X * 
  66. X * Sun RPC is provided with no support and without any obligation on the
  67. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  68. X * modification or enhancement.
  69. X * 
  70. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  71. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  72. X * OR ANY PART THEREOF.
  73. X * 
  74. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  75. X * or profits or other special, indirect and consequential damages, even if
  76. X * Sun has been advised of the possibility of such damages.
  77. X * 
  78. X * Sun Microsystems, Inc.
  79. X * 2550 Garcia Avenue
  80. X * Mountain View, California  94043
  81. X */
  82. X#ifndef lint
  83. Xstatic char sccsid[] = "@(#)xdr_float.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  84. X#endif
  85. X
  86. X/*
  87. X * xdr_float.c, Generic XDR routines impelmentation.
  88. X *
  89. X * Copyright (C) 1984, Sun Microsystems, Inc.
  90. X *
  91. X * These are the "floating point" xdr routines used to (de)serialize
  92. X * most common data items.  See xdr.h for more info on the interface to
  93. X * xdr.
  94. X */
  95. X
  96. X#include "types.h"
  97. X#include "xdr.h"
  98. X#include <stdio.h>
  99. X
  100. X/*
  101. X * NB: Not portable.
  102. X * This routine works on Suns (Sky / 68000's) and Vaxen.
  103. X */
  104. X   
  105. X/* What IEEE single precision floating point looks like on a Vax */
  106. Xstruct  ieee_single {
  107. X    unsigned int    mantissa: 23;
  108. X    unsigned int    exp     : 8;
  109. X    unsigned int    sign    : 1;
  110. X};
  111. X
  112. X/* Vax single precision floating point */
  113. Xstruct  vax_single {
  114. X    unsigned int    mantissa1 : 7;
  115. X    unsigned int    exp       : 8;
  116. X    unsigned int    sign      : 1;
  117. X    unsigned int    mantissa2 : 16;
  118. X        
  119. X};
  120. X
  121. X#define VAX_SNG_BIAS    0x81
  122. X#define IEEE_SNG_BIAS   0x7f
  123. Xstatic struct sgl_limits {
  124. X    struct vax_single s;
  125. X    struct ieee_single ieee;
  126. X} sgl_limits[2] = {
  127. X    {{ 0x3f, 0xff, 0x0, 0xffff },    /* Max Vax */
  128. X    { 0x0, 0xff, 0x0 }},        /* Max IEEE */
  129. X    {{ 0x0, 0x0, 0x0, 0x0 },    /* Min Vax */
  130. X    { 0x0, 0x0, 0x0 }}        /* Min IEEE */
  131. X};
  132. X
  133. Xbool_t 
  134. Xxdr_float(xdrs, fp)
  135. X    register XDR *xdrs;
  136. X    register float *fp;
  137. X{
  138. X    struct ieee_single is;
  139. X    struct vax_single vs, *vsp;
  140. X    struct sgl_limits *lim;
  141. X    int i;
  142. X
  143. X    switch (xdrs->x_op) {
  144. X
  145. X    case XDR_ENCODE:
  146. X#ifdef mc68000
  147. X        return (XDR_PUTLONG(xdrs, (long *)fp));
  148. X#else
  149. X        vs = *((struct vax_single *)fp);
  150. X        for (i = 0, lim = sgl_limits;
  151. X            i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  152. X            i++, lim++) {
  153. X            if ((vs.mantissa2 == lim->s.mantissa2) &&
  154. X                (vs.exp == lim->s.exp) &&
  155. X                (vs.mantissa1 == lim->s.mantissa1)) {
  156. X                is = lim->ieee;
  157. X                goto shipit;
  158. X            }
  159. X        }
  160. X        is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
  161. X        is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
  162. X    shipit:
  163. X        is.sign = vs.sign;
  164. X        return (XDR_PUTLONG(xdrs, (long *)&is));
  165. X#endif
  166. X
  167. X    case XDR_DECODE:
  168. X#ifdef mc68000
  169. X        return (XDR_GETLONG(xdrs, (long *)fp));
  170. X#else
  171. X        vsp = (struct vax_single *)fp;
  172. X        if (!XDR_GETLONG(xdrs, (long *)&is))
  173. X            return (FALSE);
  174. X        for (i = 0, lim = sgl_limits;
  175. X            i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  176. X            i++, lim++) {
  177. X            if ((is.exp == lim->ieee.exp) &&
  178. X                (is.mantissa = lim->ieee.mantissa)) {
  179. X                *vsp = lim->s;
  180. X                goto doneit;
  181. X            }
  182. X        }
  183. X        vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
  184. X        vsp->mantissa2 = is.mantissa;
  185. X        vsp->mantissa1 = (is.mantissa >> 16);
  186. X    doneit:
  187. X        vsp->sign = is.sign;
  188. X        return (TRUE);
  189. X#endif
  190. X
  191. X    case XDR_FREE:
  192. X        return (TRUE);
  193. X    }
  194. X    return (FALSE);
  195. X}
  196. X
  197. X/*
  198. X * This routine works on Suns (Sky / 68000's) and Vaxen.
  199. X */
  200. X
  201. X/* What IEEE double precision floating point looks like on a Vax */
  202. Xstruct  ieee_double {
  203. X    unsigned int    mantissa1 : 20;
  204. X    unsigned int    exp      : 11;
  205. X    unsigned int    sign      : 1;
  206. X    unsigned int    mantissa2 : 32;
  207. X};
  208. X/* Vax double precision floating point */
  209. Xstruct  vax_double {
  210. X    unsigned int    mantissa1 : 7;
  211. X    unsigned int    exp       : 8;
  212. X    unsigned int    sign      : 1;
  213. X    unsigned int    mantissa2 : 16;
  214. X    unsigned int    mantissa3 : 16;
  215. X    unsigned int    mantissa4 : 16;
  216. X};
  217. X
  218. X#define VAX_DBL_BIAS    0x81
  219. X#define IEEE_DBL_BIAS   0x3ff
  220. X#define MASK(nbits)     ((1 << nbits) - 1)
  221. X
  222. Xstatic struct dbl_limits {
  223. X    struct  vax_double d;
  224. X    struct  ieee_double ieee;
  225. X} dbl_limits[2] = {
  226. X    {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },    /* Max Vax */
  227. X    { 0x0, 0x7ff, 0x0, 0x0 }},            /* Max IEEE */
  228. X    {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},        /* Min Vax */
  229. X    { 0x0, 0x0, 0x0, 0x0 }}                /* Min IEEE */
  230. X};
  231. X
  232. Xbool_t           
  233. Xxdr_double(xdrs, dp)
  234. X    register XDR *xdrs;
  235. X    double *dp;
  236. X{
  237. X    register long *lp;
  238. X    struct  ieee_double id;
  239. X    struct  vax_double vd;
  240. X    register struct dbl_limits *lim;
  241. X    int i;
  242. X
  243. X    switch (xdrs->x_op) {
  244. X
  245. X    case XDR_ENCODE:
  246. X#ifdef mc68000
  247. X        lp = (long *)dp;
  248. X#else
  249. X        vd = *((struct  vax_double *)dp);
  250. X        for (i = 0, lim = dbl_limits;
  251. X            i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  252. X            i++, lim++) {
  253. X            if ((vd.mantissa4 == lim->d.mantissa4) &&
  254. X                (vd.mantissa3 == lim->d.mantissa3) &&
  255. X                (vd.mantissa2 == lim->d.mantissa2) &&
  256. X                (vd.mantissa1 == lim->d.mantissa1) &&
  257. X                (vd.exp == lim->d.exp)) {
  258. X                id = lim->ieee;
  259. X                goto shipit;
  260. X            }
  261. X        }
  262. X        id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
  263. X        id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
  264. X        id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
  265. X                (vd.mantissa3 << 13) |
  266. X                ((vd.mantissa4 >> 3) & MASK(13));
  267. X    shipit:
  268. X        id.sign = vd.sign;
  269. X        lp = (long *)&id;
  270. X#endif
  271. X        return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
  272. X
  273. X    case XDR_DECODE:
  274. X#ifdef mc68000
  275. X        lp = (long *)dp;
  276. X        return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
  277. X#else
  278. X        lp = (long *)&id;
  279. X        if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
  280. X            return (FALSE);
  281. X        for (i = 0, lim = dbl_limits;
  282. X            i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  283. X            i++, lim++) {
  284. X            if ((id.mantissa2 == lim->ieee.mantissa2) &&
  285. X                (id.mantissa1 == lim->ieee.mantissa1) &&
  286. X                (id.exp == lim->ieee.exp)) {
  287. X                vd = lim->d;
  288. X                goto doneit;
  289. X            }
  290. X        }
  291. X        vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
  292. X        vd.mantissa1 = (id.mantissa1 >> 13);
  293. X        vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
  294. X                (id.mantissa2 >> 29);
  295. X        vd.mantissa3 = (id.mantissa2 >> 13);
  296. X        vd.mantissa4 = (id.mantissa2 << 3);
  297. X    doneit:
  298. X        vd.sign = id.sign;
  299. X        *dp = *((double *)&vd);
  300. X        return (TRUE);
  301. X#endif
  302. X
  303. X    case XDR_FREE:
  304. X        return (TRUE);
  305. X    }
  306. X    return (FALSE);
  307. X}
  308. SHAR_EOF
  309. if test 6623 -ne "`wc -c < 'rpc/rpclib/xdr_float.c'`"
  310. then
  311.     echo shar: "error transmitting 'rpc/rpclib/xdr_float.c'" '(should have been 6623 characters)'
  312. fi
  313. chmod 444 'rpc/rpclib/xdr_float.c'
  314. fi
  315. echo shar: "extracting 'rpc/rpclib/xdr_mem.c'" '(4139 characters)'
  316. if test -f 'rpc/rpclib/xdr_mem.c'
  317. then
  318.     echo shar: "will not over-write existing file 'rpc/rpclib/xdr_mem.c'"
  319. else
  320. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_mem.c'
  321. X/*
  322. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  323. X * unrestricted use provided that this legend is included on all tape
  324. X * media and as a part of the software program in whole or part.  Users
  325. X * may copy or modify Sun RPC without charge, but are not authorized
  326. X * to license or distribute it to anyone else except as part of a product or
  327. X * program developed by the user.
  328. X * 
  329. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  330. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  331. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  332. X * 
  333. X * Sun RPC is provided with no support and without any obligation on the
  334. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  335. X * modification or enhancement.
  336. X * 
  337. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  338. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  339. X * OR ANY PART THEREOF.
  340. X * 
  341. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  342. X * or profits or other special, indirect and consequential damages, even if
  343. X * Sun has been advised of the possibility of such damages.
  344. X * 
  345. X * Sun Microsystems, Inc.
  346. X * 2550 Garcia Avenue
  347. X * Mountain View, California  94043
  348. X */
  349. X#ifndef lint
  350. Xstatic char sccsid[] = "@(#)xdr_mem.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  351. X#endif
  352. X
  353. X/*
  354. X * xdr_mem.h, XDR implementation using memory buffers.
  355. X *
  356. X * Copyright (C) 1984, Sun Microsystems, Inc.
  357. X *
  358. X * If you have some data to be interpreted as external data representation
  359. X * or to be converted to external data representation in a memory buffer,
  360. X * then this is the package for you.
  361. X *
  362. X */
  363. X
  364. X#include "types.h"
  365. X#include "xdr.h"
  366. X#include <netinet/in.h>
  367. X
  368. Xstatic bool_t    xdrmem_getlong();
  369. Xstatic bool_t    xdrmem_putlong();
  370. Xstatic bool_t    xdrmem_getbytes();
  371. Xstatic bool_t    xdrmem_putbytes();
  372. Xstatic u_int    xdrmem_getpos();
  373. Xstatic bool_t    xdrmem_setpos();
  374. Xstatic long *    xdrmem_inline();
  375. Xstatic void    xdrmem_destroy();
  376. X
  377. Xstatic struct    xdr_ops xdrmem_ops = {
  378. X    xdrmem_getlong,
  379. X    xdrmem_putlong,
  380. X    xdrmem_getbytes,
  381. X    xdrmem_putbytes,
  382. X    xdrmem_getpos,
  383. X    xdrmem_setpos,
  384. X    xdrmem_inline,
  385. X    xdrmem_destroy
  386. X};
  387. X
  388. X/*
  389. X * The procedure xdrmem_create initializes a stream descriptor for a
  390. X * memory buffer.  
  391. X */
  392. Xvoid
  393. Xxdrmem_create(xdrs, addr, size, op)
  394. X    register XDR *xdrs;
  395. X    caddr_t addr;
  396. X    u_int size;
  397. X    enum xdr_op op;
  398. X{
  399. X
  400. X    xdrs->x_op = op;
  401. X    xdrs->x_ops = &xdrmem_ops;
  402. X    xdrs->x_private = xdrs->x_base = addr;
  403. X    xdrs->x_handy = size;
  404. X}
  405. X
  406. Xstatic void
  407. Xxdrmem_destroy(/*xdrs*/)
  408. X    /*XDR *xdrs;*/
  409. X{
  410. X}
  411. X
  412. Xstatic bool_t
  413. Xxdrmem_getlong(xdrs, lp)
  414. X    register XDR *xdrs;
  415. X    long *lp;
  416. X{
  417. X
  418. X    if ((xdrs->x_handy -= sizeof(long)) < 0)
  419. X        return (FALSE);
  420. X    *lp = ntohl(*((long *)(xdrs->x_private)));
  421. X    xdrs->x_private += sizeof(long);
  422. X    return (TRUE);
  423. X}
  424. X
  425. Xstatic bool_t
  426. Xxdrmem_putlong(xdrs, lp)
  427. X    register XDR *xdrs;
  428. X    long *lp;
  429. X{
  430. X
  431. X    if ((xdrs->x_handy -= sizeof(long)) < 0)
  432. X        return (FALSE);
  433. X    *(long *)xdrs->x_private = htonl(*lp);
  434. X    xdrs->x_private += sizeof(long);
  435. X    return (TRUE);
  436. X}
  437. X
  438. Xstatic bool_t
  439. Xxdrmem_getbytes(xdrs, addr, len)
  440. X    register XDR *xdrs;
  441. X    caddr_t addr;
  442. X    register u_int len;
  443. X{
  444. X
  445. X    if ((xdrs->x_handy -= len) < 0)
  446. X        return (FALSE);
  447. X    bcopy(xdrs->x_private, addr, len);
  448. X    xdrs->x_private += len;
  449. X    return (TRUE);
  450. X}
  451. X
  452. Xstatic bool_t
  453. Xxdrmem_putbytes(xdrs, addr, len)
  454. X    register XDR *xdrs;
  455. X    caddr_t addr;
  456. X    register u_int len;
  457. X{
  458. X
  459. X    if ((xdrs->x_handy -= len) < 0)
  460. X        return (FALSE);
  461. X    bcopy(addr, xdrs->x_private, len);
  462. X    xdrs->x_private += len;
  463. X    return (TRUE);
  464. X}
  465. X
  466. Xstatic u_int
  467. Xxdrmem_getpos(xdrs)
  468. X    register XDR *xdrs;
  469. X{
  470. X
  471. X    return ((u_int)xdrs->x_private - (u_int)xdrs->x_base);
  472. X}
  473. X
  474. Xstatic bool_t
  475. Xxdrmem_setpos(xdrs, pos)
  476. X    register XDR *xdrs;
  477. X    u_int pos;
  478. X{
  479. X    register caddr_t newaddr = xdrs->x_base + pos;
  480. X    register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
  481. X
  482. X    if ((long)newaddr > (long)lastaddr)
  483. X        return (FALSE);
  484. X    xdrs->x_private = newaddr;
  485. X    xdrs->x_handy = (int)lastaddr - (int)newaddr;
  486. X    return (TRUE);
  487. X}
  488. X
  489. Xstatic long *
  490. Xxdrmem_inline(xdrs, len)
  491. X    register XDR *xdrs;
  492. X    int len;
  493. X{
  494. X    long *buf = 0;
  495. X
  496. X    if (xdrs->x_handy >= len) {
  497. X        xdrs->x_handy -= len;
  498. X        buf = (long *) xdrs->x_private;
  499. X        xdrs->x_private += len;
  500. X    }
  501. X    return (buf);
  502. X}
  503. SHAR_EOF
  504. if test 4139 -ne "`wc -c < 'rpc/rpclib/xdr_mem.c'`"
  505. then
  506.     echo shar: "error transmitting 'rpc/rpclib/xdr_mem.c'" '(should have been 4139 characters)'
  507. fi
  508. chmod 444 'rpc/rpclib/xdr_mem.c'
  509. fi
  510. echo shar: "extracting 'rpc/rpclib/xdr_rec.c'" '(15063 characters)'
  511. if test -f 'rpc/rpclib/xdr_rec.c'
  512. then
  513.     echo shar: "will not over-write existing file 'rpc/rpclib/xdr_rec.c'"
  514. else
  515. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_rec.c'
  516. X/*
  517. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  518. X * unrestricted use provided that this legend is included on all tape
  519. X * media and as a part of the software program in whole or part.  Users
  520. X * may copy or modify Sun RPC without charge, but are not authorized
  521. X * to license or distribute it to anyone else except as part of a product or
  522. X * program developed by the user.
  523. X * 
  524. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  525. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  526. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  527. X * 
  528. X * Sun RPC is provided with no support and without any obligation on the
  529. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  530. X * modification or enhancement.
  531. X * 
  532. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  533. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  534. X * OR ANY PART THEREOF.
  535. X * 
  536. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  537. X * or profits or other special, indirect and consequential damages, even if
  538. X * Sun has been advised of the possibility of such damages.
  539. X * 
  540. X * Sun Microsystems, Inc.
  541. X * 2550 Garcia Avenue
  542. X * Mountain View, California  94043
  543. X */
  544. X#ifndef lint
  545. Xstatic char sccsid[] = "@(#)xdr_rec.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  546. X#endif
  547. X
  548. X/*
  549. X * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
  550. X * layer above tcp (for rpc's use).
  551. X *
  552. X * Copyright (C) 1984, Sun Microsystems, Inc.
  553. X *
  554. X * These routines interface XDRSTREAMS to a tcp/ip connection.
  555. X * There is a record marking layer between the xdr stream
  556. X * and the tcp transport level.  A record is composed on one or more
  557. X * record fragments.  A record fragment is a thirty-two bit header followed
  558. X * by n bytes of data, where n is contained in the header.  The header
  559. X * is represented as a htonl(u_long).  Thegh order bit encodes
  560. X * whether or not the fragment is the last fragment of the record
  561. X * (1 => fragment is last, 0 => more fragments to follow. 
  562. X * The other 31 bits encode the byte length of the fragment.
  563. X */
  564. X
  565. X#include <stdio.h>
  566. X#include "types.h"
  567. X#include "xdr.h"
  568. X#include <sys/time.h>
  569. X#include <netinet/in.h>
  570. X
  571. Xchar *mem_alloc();
  572. X
  573. Xstatic u_int    fix_buf_size();
  574. X
  575. Xstatic bool_t    xdrrec_getlong();
  576. Xstatic bool_t    xdrrec_putlong();
  577. Xstatic bool_t    xdrrec_getbytes();
  578. Xstatic bool_t    xdrrec_putbytes();
  579. Xstatic u_int    xdrrec_getpos();
  580. Xstatic bool_t    xdrrec_setpos();
  581. Xstatic long *    xdrrec_inline();
  582. Xstatic void    xdrrec_destroy();
  583. X
  584. Xstatic struct  xdr_ops xdrrec_ops = {
  585. X    xdrrec_getlong,
  586. X    xdrrec_putlong,
  587. X    xdrrec_getbytes,
  588. X    xdrrec_putbytes,
  589. X    xdrrec_getpos,
  590. X    xdrrec_setpos,
  591. X    xdrrec_inline,
  592. X    xdrrec_destroy
  593. X};
  594. X
  595. X/*
  596. X * A record is composed of one or more record fragments.
  597. X * A record fragment is a two-byte header followed by zero to
  598. X * 2**32-1 bytes.  The header is treated as a long unsigned and is
  599. X * encode/decoded to the network via htonl/ntohl.  The low order 31 bits
  600. X * are a byte count of the fragment.  The highest order bit is a boolean:
  601. X * 1 => this fragment is the last fragment of the record,
  602. X * 0 => this fragment is followed by more fragment(s).
  603. X *
  604. X * The fragment/record machinery is not general;  it is constructed to
  605. X * meet the needs of xdr and rpc based on tcp.
  606. X */
  607. X
  608. X#define LAST_FRAG ((u_long)(1 << 31))
  609. X
  610. Xtypedef struct rec_strm {
  611. X    caddr_t tcp_handle;
  612. X    /*
  613. X     * out-goung bits
  614. X     */
  615. X    int (*writeit)();
  616. X    caddr_t out_base;    /* output buffer (points to frag header) */
  617. X    caddr_t out_finger;    /* next output position */
  618. X    caddr_t out_boundry;    /* data cannot up to this address */
  619. X    u_long *frag_header;    /* beginning of curren fragment */
  620. X    bool_t frag_sent;    /* true if buffer sent in middle of record */
  621. X    /*
  622. X     * in-coming bits
  623. X     */
  624. X    int (*readit)();
  625. X    u_long in_size;    /* fixed size of the input buffer */
  626. X    caddr_t in_base;
  627. X    caddr_t in_finger;    /* location of next byte to be had */
  628. X    caddr_t in_boundry;    /* can read up to this location */
  629. X    long fbtbc;        /* fragment bytes to be consumed */
  630. X    bool_t last_frag;
  631. X    u_int sendsize;
  632. X    u_int recvsize;
  633. X} RECSTREAM;
  634. X
  635. X
  636. X/*
  637. X * Create an xdr handle for xdrrec
  638. X * xdrrec_create fills in xdrs.  Sendsize and recvsize are
  639. X * send and recv buffer sizes (0 => use default).
  640. X * tcp_handle is an opaque handle that is passed as the first parameter to
  641. X * the procedures readit and writeit.  Readit and writeit are read and
  642. X * write respectively.   They are like the system
  643. X * calls expect that they take an opaque handle rather than an fd.
  644. X */
  645. Xvoid
  646. Xxdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
  647. X    register XDR *xdrs;
  648. X    u_int sendsize;
  649. X    u_int recvsize;
  650. X    caddr_t tcp_handle;
  651. X    int (*readit)();  /* like read, but pass it a tcp_handle, not sock */
  652. X    int (*writeit)();  /* like write, but pass it a tcp_handle, not sock */
  653. X{
  654. X    register RECSTREAM *rstrm =
  655. X        (RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
  656. X
  657. X    if (rstrm == NULL) {
  658. X        fprintf(stderr, "xdrrec_create: out of memory\n");
  659. X        /* 
  660. X         *  This is bad.  Should rework xdrrec_create to 
  661. X         *  return a handle, and in this case return NULL
  662. X         */
  663. X        return;
  664. X    }
  665. X    xdrs->x_ops = &xdrrec_ops;
  666. X    xdrs->x_private = (caddr_t)rstrm;
  667. X    rstrm->tcp_handle = tcp_handle;
  668. X    rstrm->readit = readit;
  669. X    rstrm->writeit = writeit;
  670. X    sendsize = fix_buf_size(sendsize);
  671. X    if ((rstrm->out_base = rstrm->out_finger = rstrm->out_boundry =
  672. X        mem_alloc(sendsize)) == NULL) {
  673. X        fprintf(stderr, "xdrrec_create: out of memory\n");
  674. X        return;
  675. X    }
  676. X    rstrm->frag_header = (u_long *)rstrm->out_base;
  677. X    rstrm->out_finger += sizeof(u_long);
  678. X    rstrm->out_boundry += sendsize;
  679. X    rstrm->frag_sent = FALSE;
  680. X    rstrm->in_size = recvsize = fix_buf_size(recvsize);
  681. X    if ((rstrm->in_base = rstrm->in_boundry=mem_alloc(recvsize)) == NULL) {
  682. X        fprintf(stderr, "xdrrec_create: out of memory\n");
  683. X        return;
  684. X    }
  685. X    rstrm->in_finger = (rstrm->in_boundry += recvsize);
  686. X    rstrm->fbtbc = 0;
  687. X    rstrm->last_frag = TRUE;
  688. X    rstrm->sendsize = sendsize;
  689. X    rstrm->recvsize = recvsize;
  690. X}
  691. X
  692. X
  693. X/*
  694. X * The reoutines defined below are the xdr ops which will go into the
  695. X * xdr handle filled in by xdrrec_create.
  696. X */
  697. X
  698. Xstatic bool_t
  699. Xxdrrec_getlong(xdrs, lp)
  700. X    XDR *xdrs;
  701. X    long *lp;
  702. X{
  703. X    register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  704. X    register long *buflp = (long *)(rstrm->in_finger);
  705. X    long mylong;
  706. X
  707. X    /* first try the inline, fast case */
  708. X    if ((rstrm->fbtbc >= sizeof(long)) &&
  709. X        (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) {
  710. X        *lp = ntohl(*buflp);
  711. X        rstrm->fbtbc -= sizeof(long);
  712. X        rstrm->in_finger += sizeof(long);
  713. X    } else {
  714. X        if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
  715. X            return (FALSE);
  716. X        *lp = ntohl(mylong);
  717. X    }
  718. X    return (TRUE);
  719. X}
  720. X
  721. Xstatic bool_t
  722. Xxdrrec_putlong(xdrs, lp)
  723. X    XDR *xdrs;
  724. X    long *lp;
  725. X{
  726. X    register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  727. X    register long *dest_lp = ((long *)(rstrm->out_finger));
  728. X
  729. X    if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) {
  730. X        /*
  731. X         * this case should almost never happen so the code is
  732. X         * inefficient
  733. X         */
  734. X        rstrm->out_finger -= sizeof(long);
  735. X        rstrm->frag_sent = TRUE;
  736. X        if (! flush_out(rstrm, FALSE))
  737. X            return (FALSE);
  738. X        dest_lp = ((long *)(rstrm->out_finger));
  739. X        rstrm->out_finger += sizeof(long);
  740. X    }
  741. X    *dest_lp = htonl(*lp);
  742. X    return (TRUE);
  743. X}
  744. X
  745. Xstatic bool_t  /* must manage buffers, fragments, and records */
  746. Xxdrrec_getbytes(xdrs, addr, len)
  747. X    XDR *xdrs;
  748. X    register caddr_t addr;
  749. X    register u_int len;
  750. X{
  751. X    register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  752. X    register int current;
  753. X
  754. X    while (len > 0) {
  755. X        current = rstrm->fbtbc;
  756. X        if (current == 0) {
  757. X            if (rstrm->last_frag)
  758. X                return (FALSE);
  759. X            if (! set_input_fragment(rstrm))
  760. X                return (FALSE);
  761. X            continue;
  762. X        }
  763. X        current = (len < current) ? len : current;
  764. X        if (! get_input_bytes(rstrm, addr, current))
  765. X            return (FALSE);
  766. X        addr += current; 
  767. X        rstrm->fbtbc -= current;
  768. X        len -= current;
  769. X    }
  770. X    return (TRUE);
  771. X}
  772. X
  773. Xstatic bool_t
  774. Xxdrrec_putbytes(xdrs, addr, len)
  775. X    XDR *xdrs;
  776. X    register caddr_t addr;
  777. X    register u_int len;
  778. X{
  779. X    register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  780. X    register int current;
  781. X
  782. X    while (len > 0) {
  783. X        current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger;
  784. X        current = (len < current) ? len : current;
  785. X        bcopy(addr, rstrm->out_finger, current);
  786. X        rstrm->out_finger += current;
  787. X        addr += current;
  788. X        len -= current;
  789. X        if (rstrm->out_finger == rstrm->out_boundry) {
  790. X            rstrm->frag_sent = TRUE;
  791. X            if (! flush_out(rstrm, FALSE))
  792. X                return (FALSE);
  793. X        }
  794. X    }
  795. X    return (TRUE);
  796. X}
  797. X
  798. Xstatic u_int
  799. Xxdrrec_getpos(xdrs)
  800. X    register XDR *xdrs;
  801. X{
  802. X    register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
  803. X    register u_int pos;
  804. X
  805. X    pos = lseek((int)rstrm->tcp_handle, 0, 1);
  806. X    if ((int)pos != -1)
  807. X        switch (xdrs->x_op) {
  808. X
  809. X        case XDR_ENCODE:
  810. X            pos += rstrm->out_finger - rstrm->out_base;
  811. X            break;
  812. X
  813. X        case XDR_DECODE:
  814. X            pos -= rstrm->in_boundry - rstrm->in_finger;
  815. X            break;
  816. X
  817. X        default:
  818. X            pos = (u_int) -1;
  819. X            break;
  820. X        }
  821. X    return (pos);
  822. X}
  823. X
  824. Xstatic bool_t
  825. Xxdrrec_setpos(xdrs, pos)
  826. X    register XDR *xdrs;
  827. X    u_int pos;
  828. X{
  829. X    register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
  830. X    u_int currpos = xdrrec_getpos(xdrs);
  831. X    int delta = currpos - pos;
  832. X    caddr_t newpos;
  833. X
  834. X    if ((int)currpos != -1)
  835. X        switch (xdrs->x_op) {
  836. X
  837. X        case XDR_ENCODE:
  838. X            newpos = rstrm->out_finger - delta;
  839. X            if ((newpos > (caddr_t)(rstrm->frag_header)) &&
  840. X                (newpos < rstrm->out_boundry)) {
  841. X                rstrm->out_finger = newpos;
  842. X                return (TRUE);
  843. X            }
  844. X            break;
  845. X
  846. X        case XDR_DECODE:
  847. X            newpos = rstrm->in_finger - delta;
  848. X            if ((delta < (int)(rstrm->fbtbc)) &&
  849. X                (newpos <= rstrm->in_boundry) &&
  850. X                (newpos >= rstrm->in_base)) {
  851. X                rstrm->in_finger = newpos;
  852. X                rstrm->fbtbc -= delta;
  853. X                return (TRUE);
  854. X            }
  855. X            break;
  856. X        }
  857. X    return (FALSE);
  858. X}
  859. X
  860. Xstatic long *
  861. Xxdrrec_inline(xdrs, len)
  862. X    register XDR *xdrs;
  863. X    int len;
  864. X{
  865. X    register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
  866. X    long * buf = NULL;
  867. X
  868. X    switch (xdrs->x_op) {
  869. X
  870. X    case XDR_ENCODE:
  871. X        if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
  872. X            buf = (long *) rstrm->out_finger;
  873. X            rstrm->out_finger += len;
  874. X        }
  875. X        break;
  876. X
  877. X    case XDR_DECODE:
  878. X        if ((len <= rstrm->fbtbc) &&
  879. X            ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
  880. X            buf = (long *) rstrm->in_finger;
  881. X            rstrm->fbtbc -= len;
  882. X            rstrm->in_finger += len;
  883. X        }
  884. X        break;
  885. X    }
  886. X    return (buf);
  887. X}
  888. X
  889. Xstatic void
  890. Xxdrrec_destroy(xdrs)
  891. X    register XDR *xdrs;
  892. X{
  893. X    register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
  894. X
  895. X    mem_free(rstrm->out_base, rstrm->sendsize);
  896. X    mem_free(rstrm->in_base, rstrm->recvsize);
  897. X    mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
  898. X}
  899. X
  900. X
  901. X/*
  902. X * Exported routines to manage xdr records
  903. X */
  904. X
  905. X/*
  906. X * Before reading (deserializing from the stream, one should always call
  907. X * this procedure to guarantee proper record alignment.
  908. X */
  909. Xbool_t
  910. Xxdrrec_skiprecord(xdrs)
  911. X    XDR *xdrs;
  912. X{
  913. X    register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  914. X
  915. X    while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
  916. X        if (! skip_input_bytes(rstrm, rstrm->fbtbc))
  917. X            return (FALSE);
  918. X        rstrm->fbtbc = 0;
  919. X        if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
  920. X            return (FALSE);
  921. X    }
  922. X    rstrm->last_frag = FALSE;
  923. X    return (TRUE);
  924. X}
  925. X
  926. X/*
  927. X * Look ahead fuction.
  928. X * Returns TRUE iff there is no more input in the buffer 
  929. X * after consuming the rest of the current record.
  930. X */
  931. Xbool_t
  932. Xxdrrec_eof(xdrs)
  933. X    XDR *xdrs;
  934. X{
  935. X    register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  936. X
  937. X    while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
  938. X        if (! skip_input_bytes(rstrm, rstrm->fbtbc))
  939. X            return (TRUE);
  940. X        rstrm->fbtbc = 0;
  941. X        if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
  942. X            return (TRUE);
  943. X    }
  944. X    if (rstrm->in_finger == rstrm->in_boundry)
  945. X        return (TRUE);
  946. X    return (FALSE);
  947. X}
  948. X
  949. X/*
  950. X * The client must tell the package when an end-of-record has occurred.
  951. X * The second paraemters tells whether the record should be flushed to the
  952. X * (output) tcp stream.  (This let's the package support batched or
  953. X * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
  954. X */
  955. Xbool_t
  956. Xxdrrec_endofrecord(xdrs, sendnow)
  957. X    XDR *xdrs;
  958. X    bool_t sendnow;
  959. X{
  960. X    register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  961. X    register u_long len;  /* fragment length */
  962. X
  963. X    if (sendnow || rstrm->frag_sent ||
  964. X        ((u_long)rstrm->out_finger + sizeof(u_long) >=
  965. X        (u_long)rstrm->out_boundry)) {
  966. X        rstrm->frag_sent = FALSE;
  967. X        return (flush_out(rstrm, TRUE));
  968. X    }
  969. X    len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
  970. X       sizeof(u_long);
  971. X    *(rstrm->frag_header) = htonl(len | LAST_FRAG);
  972. X    rstrm->frag_header = (u_long *)rstrm->out_finger;
  973. X    rstrm->out_finger += sizeof(u_long);
  974. X    return (TRUE);
  975. X}
  976. X
  977. X
  978. X/*
  979. X * Internal useful routines
  980. X */
  981. Xstatic bool_t
  982. Xflush_out(rstrm, eor)
  983. X    register RECSTREAM *rstrm;
  984. X    bool_t eor;
  985. X{
  986. X    register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
  987. X    register u_long len = (u_long)(rstrm->out_finger) - 
  988. X        (u_long)(rstrm->frag_header) - sizeof(u_long);
  989. X
  990. X    *(rstrm->frag_header) = htonl(len | eormask);
  991. X    len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
  992. X    if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
  993. X        != (int)len)
  994. X        return (FALSE);
  995. X    rstrm->frag_header = (u_long *)rstrm->out_base;
  996. X    rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long);
  997. X    return (TRUE);
  998. X}
  999. X
  1000. Xstatic bool_t  /* knows nothing about records!  Only about input buffers */
  1001. Xfill_input_buf(rstrm)
  1002. X    register RECSTREAM *rstrm;
  1003. X{
  1004. X    register caddr_t where = rstrm->in_base;
  1005. X    register int len = rstrm->in_size;
  1006. X
  1007. X    if (((int)rstrm->in_boundry % 2) != 0) {
  1008. X        /* keep stream odd bytes aligned with memory odd bytes */
  1009. X        where++;
  1010. X        len--;
  1011. X    }
  1012. X    if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
  1013. X        return (FALSE);
  1014. X    rstrm->in_finger = where;
  1015. X    where += len;
  1016. X    rstrm->in_boundry = where;
  1017. X    return (TRUE);
  1018. X}
  1019. X
  1020. Xstatic bool_t  /* knows nothing about records!  Only about input buffers */
  1021. Xget_input_bytes(rstrm, addr, len)
  1022. X    register RECSTREAM *rstrm;
  1023. X    register caddr_t addr;
  1024. X    register int len;
  1025. X{
  1026. X    register int current;
  1027. X
  1028. X    while (len > 0) {
  1029. X        current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
  1030. X        if (current == 0) {
  1031. X            if (! fill_input_buf(rstrm))
  1032. X                return (FALSE);
  1033. X            continue;
  1034. X        }
  1035. X        current = (len < current) ? len : current;
  1036. X        bcopy(rstrm->in_finger, addr, current);
  1037. X        rstrm->in_finger += current;
  1038. X        addr += current;
  1039. X        len -= current;
  1040. X    }
  1041. X    return (TRUE);
  1042. X}
  1043. X
  1044. Xstatic bool_t  /* next two bytes of the input stream are treated as a header */
  1045. Xset_input_fragment(rstrm)
  1046. X    register RECSTREAM *rstrm;
  1047. X{
  1048. X    u_long header;
  1049. X
  1050. X    if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
  1051. X        return (FALSE);
  1052. X    header = ntohl(header);
  1053. X    rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
  1054. X    rstrm->fbtbc = header & (~LAST_FRAG);
  1055. X    return (TRUE);
  1056. X}
  1057. X
  1058. Xstatic bool_t  /* consumes input bytes; knows nothing about records! */
  1059. Xskip_input_bytes(rstrm, cnt)
  1060. X    register RECSTREAM *rstrm;
  1061. X    int cnt;
  1062. X{
  1063. X    register int current;
  1064. X
  1065. X    while (cnt > 0) {
  1066. X        current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
  1067. X        if (current == 0) {
  1068. X            if (! fill_input_buf(rstrm))
  1069. X                return (FALSE);
  1070. X            continue;
  1071. X        }
  1072. X        current = (cnt < current) ? cnt : current;
  1073. X        rstrm->in_finger += current;
  1074. X        cnt -= current;
  1075. X    }
  1076. X    return (TRUE);
  1077. X}
  1078. X
  1079. Xstatic u_int
  1080. Xfix_buf_size(s)
  1081. X    register u_int s;
  1082. X{
  1083. X
  1084. X    if (s < 100)
  1085. X        return (3998);
  1086. X    for (; (s % 4) != 2; --s);
  1087. X    return (s);
  1088. X}
  1089. SHAR_EOF
  1090. if test 15063 -ne "`wc -c < 'rpc/rpclib/xdr_rec.c'`"
  1091. then
  1092.     echo shar: "error transmitting 'rpc/rpclib/xdr_rec.c'" '(should have been 15063 characters)'
  1093. fi
  1094. chmod 444 'rpc/rpclib/xdr_rec.c'
  1095. fi
  1096. echo shar: "extracting 'rpc/rpclib/xdr_reference.c'" '(2812 characters)'
  1097. if test -f 'rpc/rpclib/xdr_reference.c'
  1098. then
  1099.     echo shar: "will not over-write existing file 'rpc/rpclib/xdr_reference.c'"
  1100. else
  1101. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_reference.c'
  1102. X/*
  1103. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1104. X * unrestricted use provided that this legend is included on all tape
  1105. X * media and as a part of the software program in whole or part.  Users
  1106. X * may copy or modify Sun RPC without charge, but are not authorized
  1107. X * to license or distribute it to anyone else except as part of a product or
  1108. X * program developed by the user.
  1109. X * 
  1110. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1111. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1112. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1113. X * 
  1114. X * Sun RPC is provided with no support and without any obligation on the
  1115. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  1116. X * modification or enhancement.
  1117. X * 
  1118. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1119. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1120. X * OR ANY PART THEREOF.
  1121. X * 
  1122. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1123. X * or profits or other special, indirect and consequential damages, even if
  1124. X * Sun has been advised of the possibility of such damages.
  1125. X * 
  1126. X * Sun Microsystems, Inc.
  1127. X * 2550 Garcia Avenue
  1128. X * Mountain View, California  94043
  1129. X */
  1130. X#ifndef lint
  1131. Xstatic char sccsid[] = "@(#)xdr_reference.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  1132. X#endif
  1133. X
  1134. X/*
  1135. X * xdr_reference.c, Generic XDR routines impelmentation.
  1136. X *
  1137. X * Copyright (C) 1984, Sun Microsystems, Inc.
  1138. X *
  1139. X * These are the "non-trivial" xdr primitives used to serialize and de-serialize
  1140. X * "pointers".  See xdr.h for more info on the interface to xdr.
  1141. X */
  1142. X
  1143. X#include "types.h"
  1144. X#include "xdr.h"
  1145. X#include <stdio.h>
  1146. X#define LASTUNSIGNED    ((u_int)0-1)
  1147. X
  1148. Xchar *mem_alloc();
  1149. X
  1150. X/*
  1151. X * XDR an indirect pointer
  1152. X * xdr_reference is for recursively translating a structure that is
  1153. X * referenced by a pointer inside the structure that is currently being
  1154. X * translated.  pp references a pointer to storage. If *pp is null
  1155. X * the  necessary storage is allocated.
  1156. X * size is the sizeof the referneced structure.
  1157. X * proc is the routine to handle the referenced structure.
  1158. X */
  1159. Xbool_t
  1160. Xxdr_reference(xdrs, pp, size, proc)
  1161. X    register XDR *xdrs;
  1162. X    caddr_t *pp;        /* the pointer to work on */
  1163. X    u_int size;        /* size of the object pointed to */
  1164. X    xdrproc_t proc;        /* xdr routine to handle the object */
  1165. X{
  1166. X    register caddr_t loc = *pp;
  1167. X    register bool_t stat;
  1168. X
  1169. X    if (loc == NULL)
  1170. X        switch (xdrs->x_op) {
  1171. X        case XDR_FREE:
  1172. X            return (TRUE);
  1173. X
  1174. X        case XDR_DECODE:
  1175. X            *pp = loc = mem_alloc(size);
  1176. X            if (loc == NULL) {
  1177. X                fprintf(stderr,
  1178. X                    "xdr_reference: out of memory\n");
  1179. X                return (FALSE);
  1180. X            }
  1181. X            bzero(loc, (int)size);
  1182. X            break;
  1183. X    }
  1184. X
  1185. X    stat = (*proc)(xdrs, loc, LASTUNSIGNED);
  1186. X
  1187. X    if (xdrs->x_op == XDR_FREE) {
  1188. X        mem_free(loc, size);
  1189. X        *pp = NULL;
  1190. X    }
  1191. X    return (stat);
  1192. X}
  1193. SHAR_EOF
  1194. if test 2812 -ne "`wc -c < 'rpc/rpclib/xdr_reference.c'`"
  1195. then
  1196.     echo shar: "error transmitting 'rpc/rpclib/xdr_reference.c'" '(should have been 2812 characters)'
  1197. fi
  1198. chmod 444 'rpc/rpclib/xdr_reference.c'
  1199. fi
  1200. echo shar: "extracting 'rpc/rpclib/xdr_stdio.c'" '(4653 characters)'
  1201. if test -f 'rpc/rpclib/xdr_stdio.c'
  1202. then
  1203.     echo shar: "will not over-write existing file 'rpc/rpclib/xdr_stdio.c'"
  1204. else
  1205. sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/xdr_stdio.c'
  1206. X/*
  1207. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1208. X * unrestricted use provided that this legend is included on all tape
  1209. X * media and as a part of the software program in whole or part.  Users
  1210. X * may copy or modify Sun RPC without charge, but are not authorized
  1211. X * to license or distribute it to anyone else except as part of a product or
  1212. X * program developed by the user.
  1213. X * 
  1214. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1215. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1216. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1217. X * 
  1218. X * Sun RPC is provided with no support and without any obligation on the
  1219. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  1220. X * modification or enhancement.
  1221. X * 
  1222. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1223. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1224. X * OR ANY PART THEREOF.
  1225. X * 
  1226. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1227. X * or profits or other special, indirect and consequential damages, even if
  1228. X * Sun has been advised of the possibility of such damages.
  1229. X * 
  1230. X * Sun Microsystems, Inc.
  1231. X * 2550 Garcia Avenue
  1232. X * Mountain View, California  94043
  1233. X */
  1234. X#ifndef lint
  1235. Xstatic char sccsid[] = "@(#)xdr_stdio.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  1236. X#endif
  1237. X
  1238. X/*
  1239. X * xdr_stdio.c, XDR implementation on standard i/o file.
  1240. X *
  1241. X * Copyright (C) 1984, Sun Microsystems, Inc.
  1242. X *
  1243. X * This set of routines implements a XDR on a stdio stream.
  1244. X * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
  1245. X * from the stream.
  1246. X */
  1247. X
  1248. X#include "types.h"
  1249. X#include <stdio.h>
  1250. X#include "xdr.h"
  1251. X
  1252. Xstatic bool_t    xdrstdio_getlong();
  1253. Xstatic bool_t    xdrstdio_putlong();
  1254. Xstatic bool_t    xdrstdio_getbytes();
  1255. Xstatic bool_t    xdrstdio_putbytes();
  1256. Xstatic u_int    xdrstdio_getpos();
  1257. Xstatic bool_t    xdrstdio_setpos();
  1258. Xstatic long *    xdrstdio_inline();
  1259. Xstatic void    xdrstdio_destroy();
  1260. X
  1261. X/*
  1262. X * Ops vector for stdio type XDR
  1263. X */
  1264. Xstatic struct xdr_ops    xdrstdio_ops = {
  1265. X    xdrstdio_getlong,    /* deseraialize a long int */
  1266. X    xdrstdio_putlong,    /* seraialize a long int */
  1267. X    xdrstdio_getbytes,    /* deserialize counted bytes */
  1268. X    xdrstdio_putbytes,    /* serialize counted bytes */
  1269. X    xdrstdio_getpos,    /* get offset in the stream */
  1270. X    xdrstdio_setpos,    /* set offset in the stream */
  1271. X    xdrstdio_inline,    /* prime stream for inline macros */
  1272. X    xdrstdio_destroy    /* destroy stream */
  1273. X};
  1274. X
  1275. X/*
  1276. X * Initialize a stdio xdr stream.
  1277. X * Sets the xdr stream handle xdrs for use on the stream file.
  1278. X * Operation flag is set to op.
  1279. X */
  1280. Xvoid
  1281. Xxdrstdio_create(xdrs, file, op)
  1282. X    register XDR *xdrs;
  1283. X    FILE *file;
  1284. X    enum xdr_op op;
  1285. X{
  1286. X
  1287. X    xdrs->x_op = op;
  1288. X    xdrs->x_ops = &xdrstdio_ops;
  1289. X    xdrs->x_private = (caddr_t)file;
  1290. X    xdrs->x_handy = 0;
  1291. X    xdrs->x_base = 0;
  1292. X}
  1293. X
  1294. X/*
  1295. X * Destroy a stdio xdr stream.
  1296. X * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
  1297. X */
  1298. Xstatic void
  1299. Xxdrstdio_destroy(xdrs)
  1300. X    register XDR *xdrs;
  1301. X{
  1302. X    (void)fflush((FILE *)xdrs->x_private);
  1303. X    /* xx should we close the file ?? */
  1304. X};
  1305. X
  1306. Xstatic bool_t
  1307. Xxdrstdio_getlong(xdrs, lp)
  1308. X    XDR *xdrs;
  1309. X    register long *lp;
  1310. X{
  1311. X
  1312. X    if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
  1313. X        return (FALSE);
  1314. X#ifndef mc68000
  1315. X    *lp = ntohl(*lp);
  1316. X#endif
  1317. X    return (TRUE);
  1318. X}
  1319. X
  1320. Xstatic bool_t
  1321. Xxdrstdio_putlong(xdrs, lp)
  1322. X    XDR *xdrs;
  1323. X    long *lp;
  1324. X{
  1325. X
  1326. X#ifndef mc68000
  1327. X    long mycopy = htonl(*lp);
  1328. X    lp = &mycopy;
  1329. X#endif
  1330. X    if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
  1331. X        return (FALSE);
  1332. X    return (TRUE);
  1333. X}
  1334. X
  1335. Xstatic bool_t
  1336. Xxdrstdio_getbytes(xdrs, addr, len)
  1337. X    XDR *xdrs;
  1338. X    caddr_t addr;
  1339. X    u_int len;
  1340. X{
  1341. X
  1342. X    if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
  1343. X        return (FALSE);
  1344. X    return (TRUE);
  1345. X}
  1346. X
  1347. Xstatic bool_t
  1348. Xxdrstdio_putbytes(xdrs, addr, len)
  1349. X    XDR *xdrs;
  1350. X    caddr_t addr;
  1351. X    u_int len;
  1352. X{
  1353. X
  1354. X    if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
  1355. X        return (FALSE);
  1356. X    return (TRUE);
  1357. X}
  1358. X
  1359. Xstatic u_int
  1360. Xxdrstdio_getpos(xdrs)
  1361. X    XDR *xdrs;
  1362. X{
  1363. X
  1364. X    return ((u_int) ftell((FILE *)xdrs->x_private));
  1365. X}
  1366. X
  1367. Xstatic bool_t
  1368. Xxdrstdio_setpos(xdrs, pos) 
  1369. X    XDR *xdrs;
  1370. X    u_int pos;
  1371. X{ 
  1372. X
  1373. X    return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
  1374. X        FALSE : TRUE);
  1375. X}
  1376. X
  1377. Xstatic long *
  1378. Xxdrstdio_inline(xdrs, len)
  1379. X    XDR *xdrs;
  1380. X    u_int len;
  1381. X{
  1382. X
  1383. X    /*
  1384. X     * Must do some work to implement this: must insure
  1385. X     * enough data in the underlying stdio buffer,
  1386. X     * that the buffer is aligned so that we can indirect through a
  1387. X     * long *, and stuff this pointer in xdrs->x_buf.  Doing
  1388. X     * a fread or fwrite to a scratch buffer would defeat
  1389. X     * most of the gains to be had here and require storage
  1390. X     * management on this buffer, so we don't do this.
  1391. X     */
  1392. X    return (NULL);
  1393. X}
  1394. SHAR_EOF
  1395. if test 4653 -ne "`wc -c < 'rpc/rpclib/xdr_stdio.c'`"
  1396. then
  1397.     echo shar: "error transmitting 'rpc/rpclib/xdr_stdio.c'" '(should have been 4653 characters)'
  1398. fi
  1399. chmod 444 'rpc/rpclib/xdr_stdio.c'
  1400. fi
  1401. echo shar: "extracting 'rpc/tools/portmap.8c'" '(1034 characters)'
  1402. if test -f 'rpc/tools/portmap.8c'
  1403. then
  1404.     echo shar: "will not over-write existing file 'rpc/tools/portmap.8c'"
  1405. else
  1406. sed 's/^X//' << \SHAR_EOF > 'rpc/tools/portmap.8c'
  1407. X.\" @(#)portmap.8c 1.1 85/12/28 SMI;
  1408. X.TH PORTMAP 8C "1 February 1985"
  1409. X.SH NAME
  1410. Xportmap \- DARPA port to RPC program number mapper
  1411. X.SH SYNOPSIS
  1412. X.B /usr/etc/rpc.portmap
  1413. X.SH DESCRIPTION
  1414. X.IX  "portmap command"  ""  "\fLportmap\fP \(em DARPA to RPC mapper"
  1415. X.IX  "DARPA to RPC mapper"  ""  "DARPA to RPC mapper \(em \fLportmap\fP"
  1416. X.I Portmap
  1417. Xis a server that converts RPC program numbers
  1418. Xinto DARPA protocol port numbers.
  1419. XIt must be running in order to make RPC calls.
  1420. X.PP
  1421. XWhen an RPC server is started, it will tell
  1422. X.I portmap
  1423. Xwhat port number it is listening to,
  1424. Xand what RPC program numbers it is prepared to serve.
  1425. XWhen a client wishes to make an RPC call to a given program number,
  1426. Xit will first contact
  1427. X.I portmap
  1428. Xon the server machine to determine
  1429. Xthe port number where RPC packets should be sent.
  1430. X.PP
  1431. XNormally, standard RPC servers are started by
  1432. X.IR inetd (8c),
  1433. Xso
  1434. X.I portmap
  1435. Xmust be started before
  1436. X.I inetd
  1437. Xis invoked.
  1438. X.SH "SEE ALSO"
  1439. Xservers(5), rpcinfo(8), inetd(8)
  1440. X.SH BUGS
  1441. XIf
  1442. X.I portmap
  1443. Xcrashes, all servers must be restarted.
  1444. SHAR_EOF
  1445. if test 1034 -ne "`wc -c < 'rpc/tools/portmap.8c'`"
  1446. then
  1447.     echo shar: "error transmitting 'rpc/tools/portmap.8c'" '(should have been 1034 characters)'
  1448. fi
  1449. chmod 444 'rpc/tools/portmap.8c'
  1450. fi
  1451. echo shar: "extracting 'rpc/tools/portmap.c'" '(10290 characters)'
  1452. if test -f 'rpc/tools/portmap.c'
  1453. then
  1454.     echo shar: "will not over-write existing file 'rpc/tools/portmap.c'"
  1455. else
  1456. sed 's/^X//' << \SHAR_EOF > 'rpc/tools/portmap.c'
  1457. X#ifndef lint
  1458. Xstatic    char sccsid[] = "@(#)portmap.c 1.1 86/02/03 Copyr 1984 Sun Micro";
  1459. X#endif
  1460. X
  1461. X/*
  1462. X * Copyright (c) 1984 by Sun Microsystems, Inc.
  1463. X */
  1464. X
  1465. X/*
  1466. X * portmap.c, Implements the program,version to port number mapping for
  1467. X * rpc.
  1468. X */
  1469. X
  1470. X/*
  1471. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1472. X * unrestricted use provided that this legend is included on all tape
  1473. X * media and as a part of the software program in whole or part.  Users
  1474. X * may copy or modify Sun RPC without charge, but are not authorized
  1475. X * to license or distribute it to anyone else except as part of a product or
  1476. X * program developed by the user.
  1477. X * 
  1478. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1479. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1480. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1481. X * 
  1482. X * Sun RPC is provided with no support and without any obligation on the
  1483. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  1484. X * modification or enhancement.
  1485. X * 
  1486. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1487. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1488. X * OR ANY PART THEREOF.
  1489. X * 
  1490. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1491. X * or profits or other special, indirect and consequential damages, even if
  1492. X * Sun has been advised of the possibility of such damages.
  1493. X * 
  1494. X * Sun Microsystems, Inc.
  1495. X * 2550 Garcia Avenue
  1496. X * Mountain View, California  94043
  1497. X */
  1498. X
  1499. X#include <rpc/rpc.h>
  1500. X#include <rpc/pmap_prot.h>
  1501. X#include <stdio.h>
  1502. X#include <netdb.h>
  1503. X#include <sys/socket.h>
  1504. X#include <sys/time.h>
  1505. X#include <sys/ioctl.h>
  1506. X
  1507. Xchar *malloc();
  1508. Xint reg_service();
  1509. Xstatic int debugging = 0;
  1510. X
  1511. Xmain()
  1512. X{
  1513. X    SVCXPRT *xprt;
  1514. X    int sock, pid, t;
  1515. X    struct sockaddr_in addr;
  1516. X    int len = sizeof(struct sockaddr_in);
  1517. X
  1518. X#ifndef DEBUG
  1519. X    pid = fork();
  1520. X    if (pid < 0) {
  1521. X        perror("portmap: fork");
  1522. X        exit(1);
  1523. X    }
  1524. X    if (pid != 0)
  1525. X        exit(0);
  1526. X    for (t = 0; t < 20; t++)
  1527. X        close(t);
  1528. X     open("/", 0);
  1529. X     dup2(0, 1);
  1530. X     dup2(0, 2);
  1531. X     t = open("/dev/tty", 2);
  1532. X     if (t >= 0) {
  1533. X         ioctl(t, TIOCNOTTY, (char *)0);
  1534. X         close(t);
  1535. X     }
  1536. X#endif
  1537. X    if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  1538. X        perror("portmap cannot create socket");
  1539. X        exit(1);
  1540. X    }
  1541. X
  1542. X    addr.sin_addr.S_un.S_addr = 0;
  1543. X    addr.sin_family = AF_INET;
  1544. X    addr.sin_port = htons(PMAPPORT);
  1545. X    if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
  1546. X        perror("portmap cannot bind");
  1547. X        exit(1);
  1548. X    }
  1549. X
  1550. X    if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
  1551. X        fprintf(stderr, "couldn't do udp_create\n");
  1552. X        exit(1);
  1553. X    }
  1554. X
  1555. X    if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
  1556. X        perror("portmap cannot create socket");
  1557. X        exit(1);
  1558. X    }
  1559. X    if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
  1560. X        perror("portmap cannot bind");
  1561. X        exit(1);
  1562. X    }
  1563. X    if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))
  1564. X        == (SVCXPRT *)NULL) {
  1565. X        fprintf(stderr, "couldn't do tcp_create\n");
  1566. X        exit(1);
  1567. X    }
  1568. X
  1569. X        (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
  1570. X    svc_run();
  1571. X    fprintf(stderr, "run_svc returned unexpectedly\n");
  1572. X    abort();
  1573. X}
  1574. X
  1575. Xstruct pmaplist *pmaplist;
  1576. X
  1577. Xstatic struct pmaplist *
  1578. Xfind_service(prog, vers, prot)
  1579. X    u_long prog;
  1580. X    u_long vers;
  1581. X{
  1582. X    register struct pmaplist *hit = NULL;
  1583. X    register struct pmaplist *pml;
  1584. X
  1585. X    for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
  1586. X        if ((pml->pml_map.pm_prog != prog) ||
  1587. X            (pml->pml_map.pm_prot != prot))
  1588. X            continue;
  1589. X        hit = pml;
  1590. X        if (pml->pml_map.pm_vers == vers)
  1591. X            break;
  1592. X    }
  1593. X    return (hit);
  1594. X}
  1595. X
  1596. X/* 
  1597. X * 1 OK, 0 not
  1598. X */
  1599. Xreg_service(rqstp, xprt)
  1600. X    struct svc_req *rqstp;
  1601. X    SVCXPRT *xprt;
  1602. X{
  1603. X    struct pmap reg;
  1604. X    struct pmaplist *pml, *prevpml, *fnd;
  1605. X    int ans, port;
  1606. X    caddr_t t;
  1607. X    
  1608. X#ifdef DEBUG
  1609. X    fprintf(stderr, "server: about do a switch\n");
  1610. X#endif
  1611. X    switch (rqstp->rq_proc) {
  1612. X
  1613. X    case PMAPPROC_NULL:
  1614. X        /*
  1615. X         * Null proc call
  1616. X         */
  1617. X        if ((!svc_sendreply(xprt, xdr_void, NULL)) && debugging) {
  1618. X            abort();
  1619. X        }
  1620. X        break;
  1621. X
  1622. X    case PMAPPROC_SET:
  1623. X        /*
  1624. X         * Set a program,version to port mapping
  1625. X         */
  1626. X        if (!svc_getargs(xprt, xdr_pmap, ®))
  1627. X            svcerr_decode(xprt);
  1628. X        else {
  1629. X            /*
  1630. X             * check to see if already used
  1631. X             * find_service returns a hit even if
  1632. X             * the versions don't match, so check for it
  1633. X             */
  1634. X            fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
  1635. X            if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
  1636. X                if (fnd->pml_map.pm_port == reg.pm_port) {
  1637. X                    ans = 1;
  1638. X                    goto done;
  1639. X                }
  1640. X                else {
  1641. X                    ans = 0;
  1642. X                    goto done;
  1643. X                }
  1644. X            } else {
  1645. X                /* 
  1646. X                 * add to END of list
  1647. X                 */
  1648. X                pml = (struct pmaplist *)
  1649. X                    malloc((u_int)sizeof(struct pmaplist));
  1650. X                pml->pml_map = reg;
  1651. X                pml->pml_next = 0;
  1652. X                if (pmaplist == 0) {
  1653. X                    pmaplist = pml;
  1654. X                } else {
  1655. X                    for (fnd= pmaplist; fnd->pml_next != 0;
  1656. X                        fnd = fnd->pml_next);
  1657. X                    fnd->pml_next = pml;
  1658. X                }
  1659. X                ans = 1;
  1660. X            }
  1661. X        done:
  1662. X            if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
  1663. X                debugging) {
  1664. X                fprintf(stderr, "svc_sendreply\n");
  1665. X                abort();
  1666. X            }
  1667. X        }
  1668. X        break;
  1669. X
  1670. X    case PMAPPROC_UNSET:
  1671. X        /*
  1672. X         * Remove a program,version to port mapping.
  1673. X         */
  1674. X        if (!svc_getargs(xprt, xdr_pmap, ®))
  1675. X            svcerr_decode(xprt);
  1676. X        else {
  1677. X            ans = 0;
  1678. X            for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
  1679. X                if ((pml->pml_map.pm_prog != reg.pm_prog) ||
  1680. X                    (pml->pml_map.pm_vers != reg.pm_vers)) {
  1681. X                    /* both pml & prevpml move forwards */
  1682. X                    prevpml = pml;
  1683. X                    pml = pml->pml_next;
  1684. X                    continue;
  1685. X                }
  1686. X                /* found it; pml moves forward, prevpml stays */
  1687. X                ans = 1;
  1688. X                t = (caddr_t)pml;
  1689. X                pml = pml->pml_next;
  1690. X                if (prevpml == NULL)
  1691. X                    pmaplist = pml;
  1692. X                else
  1693. X                    prevpml->pml_next = pml;
  1694. X                free(t);
  1695. X            }
  1696. X            if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
  1697. X                debugging) {
  1698. X                fprintf(stderr, "svc_sendreply\n");
  1699. X                abort();
  1700. X            }
  1701. X        }
  1702. X        break;
  1703. X
  1704. X    case PMAPPROC_GETPORT:
  1705. X        /*
  1706. X         * Lookup the mapping for a program,version and return its port
  1707. X         */
  1708. X        if (!svc_getargs(xprt, xdr_pmap, ®))
  1709. X            svcerr_decode(xprt);
  1710. X        else {
  1711. X            fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
  1712. X            if (fnd)
  1713. X                port = fnd->pml_map.pm_port;
  1714. X            else
  1715. X                port = 0;
  1716. X            if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) &&
  1717. X                debugging) {
  1718. X                fprintf(stderr, "svc_sendreply\n");
  1719. X                abort();
  1720. X            }
  1721. X        }
  1722. X        break;
  1723. X
  1724. X    case PMAPPROC_DUMP:
  1725. X        /*
  1726. X         * Return the current set of mapped program,version
  1727. X         */
  1728. X        if (!svc_getargs(xprt, xdr_void, NULL))
  1729. X            svcerr_decode(xprt);
  1730. X        else {
  1731. X            if ((!svc_sendreply(xprt, xdr_pmaplist,
  1732. X                (caddr_t)&pmaplist)) && debugging) {
  1733. X                fprintf(stderr, "svc_sendreply\n");
  1734. X                abort();
  1735. X            }
  1736. X        }
  1737. X        break;
  1738. X
  1739. X    case PMAPPROC_CALLIT:
  1740. X        /*
  1741. X         * Calls a procedure on the local machine.  If the requested
  1742. X         * procedure is not registered this procedure does not return
  1743. X         * error information!!
  1744. X         * This procedure is only supported on rpc/udp and calls via 
  1745. X         * rpc/udp.  It passes null authentication parameters.
  1746. X         */
  1747. X        callit(rqstp, xprt);
  1748. X        break;
  1749. X
  1750. X    default:
  1751. X        svcerr_noproc(xprt);
  1752. X        break;
  1753. X    }
  1754. X}
  1755. X
  1756. X
  1757. X/*
  1758. X * Stuff for the rmtcall service
  1759. X */
  1760. X#define ARGSIZE 9000
  1761. X
  1762. Xtypedef struct encap_parms {
  1763. X    u_long arglen;
  1764. X    char *args;
  1765. X};
  1766. X
  1767. Xstatic bool_t
  1768. Xxdr_encap_parms(xdrs, epp)
  1769. X    XDR *xdrs;
  1770. X    struct encap_parms *epp;
  1771. X{
  1772. X
  1773. X    return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE));
  1774. X}
  1775. X
  1776. Xtypedef struct rmtcallargs {
  1777. X    u_long    rmt_prog;
  1778. X    u_long    rmt_vers;
  1779. X    u_long    rmt_port;
  1780. X    u_long    rmt_proc;
  1781. X    struct encap_parms rmt_args;
  1782. X};
  1783. X
  1784. Xstatic bool_t
  1785. Xxdr_rmtcall_args(xdrs, cap)
  1786. X    register XDR *xdrs;
  1787. X    register struct rmtcallargs *cap;
  1788. X{
  1789. X
  1790. X    /* does not get a port number */
  1791. X    if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
  1792. X        xdr_u_long(xdrs, &(cap->rmt_vers)) &&
  1793. X        xdr_u_long(xdrs, &(cap->rmt_proc))) {
  1794. X        return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
  1795. X    }
  1796. X    return (FALSE);
  1797. X}
  1798. X
  1799. Xstatic bool_t
  1800. Xxdr_rmtcall_result(xdrs, cap)
  1801. X    register XDR *xdrs;
  1802. X    register struct rmtcallargs *cap;
  1803. X{
  1804. X    if (xdr_u_long(xdrs, &(cap->rmt_port)))
  1805. X        return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
  1806. X    return (FALSE);
  1807. X}
  1808. X
  1809. X/*
  1810. X * only worries about the struct encap_parms part of struct rmtcallargs.
  1811. X * The arglen must already be set!!
  1812. X */
  1813. Xstatic bool_t
  1814. Xxdr_opaque_parms(xdrs, cap)
  1815. X    XDR *xdrs;
  1816. X    struct rmtcallargs *cap;
  1817. X{
  1818. X
  1819. X    return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
  1820. X}
  1821. X
  1822. X/*
  1823. X * This routine finds and sets the length of incoming opaque paraters
  1824. X * and then calls xdr_opaque_parms.
  1825. X */
  1826. Xstatic bool_t
  1827. Xxdr_len_opaque_parms(xdrs, cap)
  1828. X    register XDR *xdrs;
  1829. X    struct rmtcallargs *cap;
  1830. X{
  1831. X    register u_int beginpos, lowpos, highpos, currpos, pos;
  1832. X
  1833. X    beginpos = lowpos = pos = xdr_getpos(xdrs);
  1834. X    highpos = lowpos + ARGSIZE;
  1835. X    while ((int)(highpos - lowpos) >= 0) {
  1836. X        currpos = (lowpos + highpos) / 2;
  1837. X        if (xdr_setpos(xdrs, currpos)) {
  1838. X            pos = currpos;
  1839. X            lowpos = currpos + 1;
  1840. X        } else {
  1841. X            highpos = currpos - 1;
  1842. X        }
  1843. X    }
  1844. X    xdr_setpos(xdrs, beginpos);
  1845. X    cap->rmt_args.arglen = pos - beginpos;
  1846. X    return (xdr_opaque_parms(xdrs, cap));
  1847. X}
  1848. X
  1849. X/*
  1850. X * Call a remote procedure service
  1851. X * This procedure is very quiet when things go wrong.
  1852. X * The proc is written to support broadcast rpc.  In the broadcast case,
  1853. X * a machine should shut-up instead of complain, less the requestor be
  1854. X * overrun with complaints at the expense of not hearing a valid reply ...
  1855. X */
  1856. Xstatic
  1857. Xcallit(rqstp, xprt)
  1858. X    struct svc_req *rqstp;
  1859. X    SVCXPRT *xprt;
  1860. X{
  1861. X    char buf[2000];
  1862. X    struct rmtcallargs a;
  1863. X    struct pmaplist *pml;
  1864. X    u_short port;
  1865. X    struct sockaddr_in me;
  1866. X    int socket = -1;
  1867. X    CLIENT *client;
  1868. X    struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
  1869. X    struct timeval timeout;
  1870. X
  1871. X    timeout.tv_sec = 5;
  1872. X    timeout.tv_usec = 0;
  1873. X    a.rmt_args.args = buf;
  1874. X    if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
  1875. X        return;
  1876. X    if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)
  1877. X        return;
  1878. X    port = pml->pml_map.pm_port;
  1879. X    get_myaddress(&me);
  1880. X    me.sin_port = htons(port);
  1881. X    client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);
  1882. X    if (client != (CLIENT *)NULL) {
  1883. X        if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
  1884. X            client->cl_auth = authunix_create(au->aup_machname,
  1885. X               au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
  1886. X        }
  1887. X        a.rmt_port = (u_long)port;
  1888. X        if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
  1889. X            xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
  1890. X            svc_sendreply(xprt, xdr_rmtcall_result, &a);
  1891. X        }
  1892. X        AUTH_DESTROY(client->cl_auth);
  1893. X        clnt_destroy(client);
  1894. X    }
  1895. X    (void)close(socket);
  1896. X}
  1897. SHAR_EOF
  1898. if test 10290 -ne "`wc -c < 'rpc/tools/portmap.c'`"
  1899. then
  1900.     echo shar: "error transmitting 'rpc/tools/portmap.c'" '(should have been 10290 characters)'
  1901. fi
  1902. chmod 444 'rpc/tools/portmap.c'
  1903. fi
  1904. exit 0
  1905. #    End of shell archive
  1906.  
  1907.